import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { CollapseModule } from './collapse.module';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';

@Component({
  template: `
    <lv-collapse
      [lvMultiExpansion]="multiExpansion"
      [lvType]="type"
      [lvSize]="size"
      [lvBeforeExpanded]="beforeExpanded"
      [lvAfterExpanded]="afterExpanded"
      [lvBeforeCollapsed]="beforeCollapsed"
      [lvAfterCollapsed]="afterCollapsed"
    >
      <lv-collapse-panel [lvTitle]="'Panel 001'" [lvDisabled]="disabled" [lvLoading]="loading">
        <div>
          This is content1...
          <br />
          This is content1...
          <br />
        </div>
      </lv-collapse-panel>
      <lv-collapse-panel [lvTitle]="'Panel 002'">
        <div>
          This is content2...
          <br />
          This is content2...
          <br />
        </div>
      </lv-collapse-panel>
      <lv-collapse-panel [lvTitle]="'Panel 003'">
        <div>
          This is content3...
          <br />
          This is content3...
          <br />
        </div>
      </lv-collapse-panel>
    </lv-collapse>
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
class TestCollapseComponent {
  multiExpansion = true;
  type = 'default';
  size = 'default';
  disabled = false;
  loading = false;

  beforeE = false;
  afterE = false;
  beforeC = false;
  afterC = false;
  beforeExpanded = () => {
    this.beforeE = true;
  };
  afterExpanded = () => {
    this.afterE = true;
  };
  beforeCollapsed = () => {
    this.beforeC = true;
  };
  afterCollapsed = () => {
    this.afterC = true;
  };
}

describe('CollapseComponent', () => {
  beforeEach(
    waitForAsync(() => {
      TestBed.configureTestingModule({
        declarations: [TestCollapseComponent],
        imports: [CollapseModule, NoopAnimationsModule],
        teardown: { destroyAfterEach: true },
      }).compileComponents();
    })
  );

  describe('render', () => {
    let component: TestCollapseComponent;
    let fixture: ComponentFixture<TestCollapseComponent>;
    const renderComp = fakeAsync(para => {
      for (const [key, value] of Object.entries(para)) {
        component[key] = value;
      }
      fixture.detectChanges();
      tick(1500);
      fixture.detectChanges();
      expect(fixture).toMatchSnapshot();
      tick(1500);
    });

    beforeEach(() => {
      fixture = TestBed.createComponent(TestCollapseComponent);
      component = fixture.componentInstance;
    });

    it('with lvType simple', () => {
      renderComp({ type: 'simple' });
    });

    it('with lvSize large', () => {
      renderComp({ size: 'large' });
    });

    it('with lvDisabled', () => {
      renderComp({ disabled: true });
    });

    it('with lvLoading', () => {
      renderComp({ loading: true });
    });
  });

  describe('work', () => {
    let component: TestCollapseComponent;
    let fixture: ComponentFixture<TestCollapseComponent>;

    beforeEach(fakeAsync(() => {
      fixture = TestBed.createComponent(TestCollapseComponent);
      component = fixture.componentInstance;
      fixture.detectChanges();
      tick(1500);
      fixture.detectChanges();
    }));

    // 正常展开多个，点击关闭
    it('should work when expanded', fakeAsync(() => {
      const panels = fixture.nativeElement.querySelectorAll('.lv-collapse-header');
      const body = fixture.nativeElement.querySelectorAll('.lv-collapse-body');
      expect(body.length).toBe(0);
      expect(component.beforeE).toBe(false);
      expect(component.afterE).toBe(false);

      panels[1].dispatchEvent(new Event('click'));
      panels[2].dispatchEvent(new Event('click'));
      fixture.detectChanges();
      tick(1500);
      fixture.detectChanges();
      tick(1500);
      const bodyAfter = fixture.nativeElement.querySelectorAll('.lv-collapse-body');
      expect(bodyAfter.length).toBe(2);
      expect(component.beforeE).toBe(true);
      expect(component.afterE).toBe(true);

      panels[1].dispatchEvent(new Event('click'));
      fixture.detectChanges();
      tick(1500);
      fixture.detectChanges();
      tick(1500);
      const bodyClose = fixture.nativeElement.querySelectorAll('.lv-collapse-body');
      expect(bodyClose.length).toBe(1);
      expect(component.beforeC).toBe(true);
      expect(component.afterC).toBe(true);
    }));

    // 互斥展开，手风琴模式
    it('should work with lvMultiExpansion', fakeAsync(() => {
      component.multiExpansion = false;
      fixture.detectChanges();
      tick(1500);
      const panels = fixture.nativeElement.querySelectorAll('.lv-collapse-header');
      const body = fixture.nativeElement.querySelectorAll('.lv-collapse-body');
      expect(body.length).toBe(0);

      panels[1].dispatchEvent(new Event('click'));
      fixture.detectChanges();
      tick(1500);
      fixture.detectChanges();
      tick(1500);
      const bodyAfter = fixture.nativeElement.querySelectorAll('.lv-collapse-body');
      expect(bodyAfter.length).toBe(1);
      expect(bodyAfter[0].textContent).toContain('content2');

      panels[2].dispatchEvent(new Event('click'));
      fixture.detectChanges();
      tick(1500);
      fixture.detectChanges();
      tick(1500);
      const bodyAfter2 = fixture.nativeElement.querySelectorAll('.lv-collapse-body');
      expect(bodyAfter2.length).toBe(1);
      expect(bodyAfter2[0].textContent).toContain('content3');
    }));
  });
});
